package com.mxpio.erp.inventory.policy.impl;

import com.mxpio.erp.common.enums.OrderStatusEnums;
import com.mxpio.erp.common.inventory.entity.*;
import com.mxpio.erp.common.jpa.model.Order;
import com.mxpio.erp.common.order.policy.OrderContext;
import com.mxpio.erp.common.order.service.OrderLineService;
import com.mxpio.erp.common.technology.entity.Item;
import com.mxpio.erp.common.vo.OrderExcuteLineVo;
import com.mxpio.erp.common.workshop.entity.MoPickingNotice;
import com.mxpio.erp.common.workshop.entity.MoPickingNoticeLine;
import com.mxpio.erp.inventory.policy.AbstractWoPolicy;
import com.mxpioframework.jpa.JpaUtil;
import com.mxpioframework.security.util.SecurityUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;

import java.math.BigDecimal;
import java.util.*;

/**
 * @Author : 吴盼盼
 * @Datetime : 2022/12/1 22:24
 * @Desc :
 * @Modor :  Modifytime:
 * @modDesc :送货计划入 仓单人工确认
 */
public class FeedPlanWoInPolicy extends AbstractWoPolicy {
    private List<OrderExcuteLineVo> orderExcuteVos;
    private OrderLineService orderLineService;
    public FeedPlanWoInPolicy(List<OrderExcuteLineVo> orderExcuteVos, OrderLineService orderLineService) {
        this.orderExcuteVos = orderExcuteVos;
        this.orderLineService = orderLineService;
    }

    public void execute(OrderContext context) {
        Order order = context.getEntity();
        if(order instanceof WarehouseOrder) {
            List<OrderExcuteLineVo> orderExcuteVos = context.getOrderExcuteVos();
            List<InvFlow> invFlows = new ArrayList<>();
            for(OrderExcuteLineVo vo : orderExcuteVos) {//只考虑入的情况
                // 单据数量控制
                BigDecimal completeQuantity = context.getLotService().getMaxQuantityByWo(vo.getBizWoNo(), vo.getBizWoLineNo());
                BigDecimal maxQuantity = vo.getLineQuantity()==null?BigDecimal.ZERO:vo.getLineQuantity();
                BigDecimal currentQuan = maxQuantity.subtract(completeQuantity).subtract(vo.getQuantity());
                if(currentQuan.compareTo(BigDecimal.ZERO) < 0) {
                    context.addError("物料：" + vo.getItemCode() + "超过最大执行数量");
                    break;
                }
                //生成入流水
                String accessType = ((WarehouseOrder) order).getAccessType();
                InvFlow inFlow = new InvFlow();
                inFlow.setAccessType(accessType);
                inFlow.setItemCode(vo.getItemCode());
                inFlow.setWhCode(((WarehouseOrder) order).getWhCode());
                inFlow.setQuantity(vo.getQuantity());
                inFlow.setMemo(vo.getMemo());
                inFlow.setOriginBizNo(vo.getBizOrderNo());
                inFlow.setOriginBizType(((WarehouseOrder) order).getOriginBizType());
                inFlow.setOriginBizLineNo(vo.getBizOrderlineNo());
                inFlow.setWoBizNo(order.getBizNo());
                inFlow.setWoBizType(((WarehouseOrder) order).getWoType());
                inFlow.setWoBizLineNo(vo.getBizWoLineNo());
                inFlow.setLotNo(vo.getLotNo());
                inFlow.setSubLotIndex(vo.getSubLotIndex());//增加子批索引
                invFlows.add(inFlow);
            }
            if(CollectionUtils.isEmpty(context.getErrors())) {
                JpaUtil.save(invFlows);

                //自动生成出仓单的流水
                String originNoticeNo = ((WarehouseOrder) order).getOriginBizNo();//获取对应送货计划编码
                FeedPlanNotice feedPlanNotice = JpaUtil.linq(FeedPlanNotice.class).equal("noticeNo", originNoticeNo).findOne();
                String sourcePickingNoticeNo = feedPlanNotice.getSourcePickingNoticeNo();//源领/补料通知单
                MoPickingNotice pickingNotice = JpaUtil.linq(MoPickingNotice.class).collect("noticeNo", MoPickingNoticeLine.class, "noticeNo").equal("noticeNo", sourcePickingNoticeNo).findOne();
                List<MoPickingNoticeLine> moPickingNoticeLines = pickingNotice.getMoPickingNoticeLines();
                Map<String, MoPickingNoticeLine> pickingNoticeLineMap = JpaUtil.index(moPickingNoticeLines, "lineNo");
                List<OrderExcuteLineVo> woVos = new ArrayList<>();
                for (String mpLineNo:pickingNoticeLineMap.keySet()){
                    MoPickingNoticeLine moPickingNoticeLine = pickingNoticeLineMap.get(mpLineNo);

                    OrderExcuteLineVo excuteLineVo = new OrderExcuteLineVo();
                    excuteLineVo.setBizOrderNo(moPickingNoticeLine.getOriginBizNo());
                    excuteLineVo.setBizOrderlineNo(moPickingNoticeLine.getOriginBizLineNo());
                    excuteLineVo.setItemCode(moPickingNoticeLine.getItemCode());
                    excuteLineVo.setLineQuantity(moPickingNoticeLine.getQuantity());
                    excuteLineVo.setLotNo(moPickingNoticeLine.getLotNo());
                    excuteLineVo.setSubLotIndex(moPickingNoticeLine.getSubLotIndex());
                    excuteLineVo.setQuantity(orderExcuteVos.get(0).getQuantity());//取本次提交的执行数量
                    excuteLineVo.setWhCode(pickingNotice.getWhCode());
                    excuteLineVo.setMemo(moPickingNoticeLine.getMemo());
                    excuteLineVo.setNoticeNo(pickingNotice.getNoticeNo());
                    excuteLineVo.setNoticeLineNo(moPickingNoticeLine.getLineNo());
                    woVos.add(excuteLineVo);
                }
                WarehouseOrder outWo = JpaUtil.linq(WarehouseOrder.class).equal("originNoticeNo", sourcePickingNoticeNo).findOne();
                OrderExcuteLineVo orderExcuteLineVo = woVos.get(0);
                //自动执行，生成出流水
                InvFlow outFlow = new InvFlow();
                outFlow.setAccessType(outWo.getAccessType());
                outFlow.setItemCode(orderExcuteLineVo.getItemCode());
                outFlow.setWhCode(outWo.getWhCode());
                outFlow.setQuantity(orderExcuteLineVo.getQuantity());
                outFlow.setMemo(outWo.getMemo());
                outFlow.setOriginBizNo(outWo.getOriginBizNo());
                outFlow.setOriginBizType(outWo.getOriginBizType());
                outFlow.setOriginBizLineNo(orderExcuteLineVo.getBizOrderlineNo());
                outFlow.setWoBizNo(outWo.getBizNo());
                outFlow.setWoBizType(outWo.getWoType());
                outFlow.setWoBizLineNo("1");
                outFlow.setLotNo(orderExcuteLineVo.getLotNo());
                outFlow.setSubLotIndex(orderExcuteLineVo.getSubLotIndex());//增加子批索引
                JpaUtil.save(outFlow);
            }
        }else {
            context.addError("单据类型错误");
        }
    }

    @Override
    public OrderContext config(OrderContext context) {
        context.setOrderExcuteVos(orderExcuteVos);
        return context;
    }

    @Override
    public boolean beforeExecute(OrderContext context) {
        return true;
    }

    @Override
    public void afterExecute(OrderContext context) {
        if(CollectionUtils.isEmpty(context.getErrors())){
            Order wo = context.getEntity();
            String originNoticeNo = ((WarehouseOrder) wo).getOriginBizNo();//获取对应送货计划编码
            FeedPlanNotice feedPlanNotice = JpaUtil.linq(FeedPlanNotice.class).equal("noticeNo", originNoticeNo).findOne();
            String sourcePickingNoticeNo = feedPlanNotice.getSourcePickingNoticeNo();//源领/补料通知单
            WarehouseOrder outWo = JpaUtil.linq(WarehouseOrder.class).equal("originNoticeNo", sourcePickingNoticeNo).findOne();

            if (judgeWOCompletion(context)){
                if(StringUtils.isBlank(wo.getExecutor())) {
                    wo.setExecuteTime(new Date());
                    wo.setExecutor(SecurityUtils.getLoginUsername());

                    outWo.setExecuteTime(new Date());
                    outWo.setExecutor(SecurityUtils.getLoginUsername());
                }
                wo.setOrderStatus(OrderStatusEnums.OrderStatus.FINISHED.getStatusCode());
                JpaUtil.update(wo);
                outWo.setOrderStatus(OrderStatusEnums.OrderStatus.FINISHED.getStatusCode());
                JpaUtil.update(outWo);
            }else{
                if(OrderStatusEnums.OrderStatus.ORDERED.getStatusCode().equals(wo.getOrderStatus())||
                        OrderStatusEnums.OrderStatus.PLAN.getStatusCode().equals(wo.getOrderStatus())) {
                    wo.setOrderStatus(OrderStatusEnums.OrderStatus.PROCESSING.getStatusCode());
                    wo.setExecuteTime(new Date());
                    wo.setExecutor(SecurityUtils.getLoginUsername());
                    JpaUtil.update(wo);

                    outWo.setOrderStatus(OrderStatusEnums.OrderStatus.PROCESSING.getStatusCode());
                    outWo.setExecuteTime(new Date());
                    outWo.setExecutor(SecurityUtils.getLoginUsername());
                    JpaUtil.update(outWo);
                }
            }
        }
    }

    private boolean judgeWOCompletion(OrderContext context){//判断仓单是否已执行完毕
        Order order = context.getEntity();
        List<WarehouseOrderLine> lines = JpaUtil.linq(WarehouseOrderLine.class).equal("bizNo", order.getBizNo()).list();
        if (lines.size()>0){
            for (WarehouseOrderLine line:lines){
                BigDecimal completeQuantity = context.getLotService().getMaxQuantityByWo(line.getBizNo(), line.getLineNo());
                if (line.getQuantity().compareTo(completeQuantity)!=0){
                    return false;
                }
            }
        }else{
            return false;
        }
        return true;
    }
}
